package timing.ukulele.storage.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.storage.entity.GroupEntity;
import timing.ukulele.storage.entity.UserEntity;
import timing.ukulele.storage.service.GroupService;
import timing.ukulele.storage.service.UserService;
import timing.ukulele.storage.vo.PageVO;
import timing.ukulele.storage.vo.UserVO;
import timing.ukulele.storage.vo.map.UserMapper;
import timing.ukulele.web.controller.BaseController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户相关操作接口
 */
@RestController
@RequestMapping("/user")
@Slf4j
@Tag(name = "用户相关操作")
public class UserController extends BaseController {
    private final UserService userService;
    private final GroupService groupService;

    public UserController(UserService userService, GroupService groupService) {
        this.userService = userService;
        this.groupService = groupService;
    }

    @GetMapping("/{id}")
    @Operation(summary ="根据id获取用户")
    public ResponseData<UserEntity> findById(@Parameter(description = "用户id", required = true, example = "1") @PathVariable("id") String id) {
        UserEntity user = userService.findById(id);
        return successResponse(user);
    }

    @GetMapping("/page/{current}/{size}")
    @Operation(summary ="获取用户分页信息")
    public ResponseData<PageVO<UserVO>> page(@Parameter(description = "当前页,从1开始", required = true, example = "1", name = "current", in = ParameterIn.PATH) @PathVariable("current") Integer current,
                                             @Parameter(description = "每页大小", required = true, example = "10", name = "size", in = ParameterIn.PATH) @PathVariable("size") Integer size,
                                             @Parameter(description = "每页大小", name = "groupId", in = ParameterIn.QUERY) @RequestParam(value = "groupId", required = false) String groupId,
                                             @Parameter(description = "升序排序列,逗号隔开", example = "id,name", name = "ascBy", in = ParameterIn.QUERY) @RequestParam(value = "ascBy", required = false) String ascBy,
                                             @Parameter(description = "降序排序列,逗号隔开", example = "id,name", name = "descBy", in = ParameterIn.QUERY) @RequestParam(value = "descBy", required = false) String descBy) {
        Sort sort = null;
        if (!StringUtils.hasLength(ascBy) && !StringUtils.hasLength(descBy))
            sort = Sort.by(Sort.Order.desc("_id"));
        if (StringUtils.hasLength(ascBy)) {
            String[] split = ascBy.split(",");
            sort = Sort.by(split).ascending();
        }
        if (StringUtils.hasLength(descBy)) {
            String[] split = descBy.split(",");
            sort = Sort.by(split).descending();
        }
        Page<UserEntity> page = userService.getUserPage(current - 1, size, groupId, sort);
        List<UserVO> list = null;
        if (!CollectionUtils.isEmpty(page.getContent())) {
            list = new ArrayList<>(page.getContent().size());
            for (UserEntity entity : page.getContent()) {
//                UserVO vo = new UserVO();
//                BeanUtils.copyProperties(entity, vo);
                UserVO vo =  UserMapper.INSTANCE.entity2VO(entity);
                if (!CollectionUtils.isEmpty(entity.getGroup())) {
                    vo.setGroupName(new ArrayList<>(entity.getGroup().size()));
                    List<GroupEntity> all = groupService.getAll();
                    if (!CollectionUtils.isEmpty(all)) {
                        Map<String, String> collect = all.stream().collect(Collectors.toMap(GroupEntity::getId, GroupEntity::getName));
                        entity.getGroup().forEach(group -> {
                            entity.setPassword(null);
                            vo.getGroupName().add(collect.get(group));
                        });
                    }
                }
                list.add(vo);
            }
        }
        PageVO<UserVO> vo = new PageVO<>(current, size, page.getTotalPages(), page.getTotalElements(), list, ascBy, descBy);
        return successResponse(vo);
    }

    @PostMapping
    @Operation(summary ="添加一个用户")
    public ResponseData<UserEntity> add(@RequestBody UserEntity user) {
        if (!StringUtils.hasLength(user.getAccount()) || user.getAccount().length() < 3
                || "amazon".equalsIgnoreCase(user.getAccount()) || "share".equalsIgnoreCase(user.getAccount())) {
            return errorResponse(null, "不能使用该用户名，请重新命名");
        }
        UserEntity filter = new UserEntity();
        filter.setName(user.getAccount());
        filter.setRole(null);
        if (userService.existed(filter)) {
            return failResponse(null, "用户已存在");
        } else {
            UserEntity entity = userService.addUser(user);
            if (entity == null)
                return failResponse(null, "失败");
            return successResponse(entity);
        }
    }

    @PutMapping
    @Operation(summary ="修改用户信息")
    public ResponseData<UserEntity> modify(@RequestBody UserEntity user) {
        user.setAccount(null);
        UserEntity filter = new UserEntity();
        filter.setId(user.getId());
        filter.setRole(null);
        if (userService.existed(filter)) {
            try {
                return successResponse(userService.updateUser(user));
            } catch (IllegalAccessException e) {
                return failResponse(null, e.getMessage());
            }
        } else {
            return failResponse(null, "用户不存在");
        }
    }

    @PutMapping("/{id}/{active}")
    @Operation(summary ="启用禁用")
    public ResponseData<UserEntity> changeUserActive(@PathVariable("id") String id,
                                                     @PathVariable("active") Boolean active) {
        UserEntity filter = new UserEntity();
        filter.setId(id);
        filter.setRole(null);
        if (userService.existed(filter)) {
            try {
                filter.setActive(active);
                return successResponse(userService.updateUser(filter));
            } catch (IllegalAccessException e) {
                return failResponse(null, e.getMessage());
            }
        } else {
            return failResponse(null, "用户不存在");
        }
    }

    @DeleteMapping("/{id}")
    @Operation(summary ="删除用户信息")
    public ResponseData<Boolean> delete(@Parameter(description = "用户id", required = true, example = "1", name = "id", in = ParameterIn.PATH) @PathVariable("id") String id) {
        return userService.deleteUser(id);
    }

    @PutMapping("/password/reset/{id}")
    @Operation(summary ="重置用户密码")
    public ResponseData<String> reset(@Parameter(description = "用户id", required = true, example = "1", name = "id", in = ParameterIn.PATH) @PathVariable("id") String id) {
        try {
            return this.userService.reset(id);
        } catch (IllegalAccessException e) {
            return failResponse("重置失败：" + e.getMessage());
        }
    }
}
